//SamXIAO
#include <bits/stdc++.h>
using namespace std;

#define szARR_CNT_OF(x) sizeof(x) / sizeof(x[0])
#define TO_BOOL(x, mask) (x & mask) != 0
#if 0
#define DBG_PRINT printf
#else
#define DBG_PRINT
#endif
int n, m;
char a[100][100];
struct xy_t {
   int x, y;
   xy_t(){};
   xy_t(int x, int y) : x(x), y(y) {}
};
xy_t xyFr, xyTo;
int ans[100][100];
queue<xy_t> q;

void init() {
   memset(a, 0, sizeof(a));
   memset(ans, 0, sizeof(ans));
}

inline bool isIn(int x, int y) {
   return 0 <= x && x < n && 0 <= y && y < m;
}
void bfs(int x, int y) {
   if (!isIn(x, y) || '.' != a[x][y]) return;
   a[x][y] = '#';
   q.push(xy_t(x, y));
   while (!q.empty()) {
      xy_t xy = q.front();
      q.pop();
      x = xy.x, y = xy.y;
      DBG_PRINT("  /////////%d,%d  ", x, y);
      int dxy[][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
      for (int i = 0; i < szARR_CNT_OF(dxy); i++) {
         int nx = x + dxy[i][0], ny = y + dxy[i][1];
         if (isIn(nx, ny) && '.' == a[nx][ny]) {
            a[nx][ny] = '#';
            q.push(xy_t(nx, ny));
            ans[nx][ny] = ans[x][y] + 1;
            DBG_PRINT(">%d,%d  ", nx, ny);
         }
      }
      DBG_PRINT("\n");
   }
}

void dump() {
   DBG_PRINT("\n");
   for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) DBG_PRINT("%c", a[i][j]);
      DBG_PRINT("\n");
   }
   DBG_PRINT(" =============\n");
}

void work1() {
   while (true) {
      scanf("%d%d", &n, &m);
      init();
      if (0 == n && 0 == m) break;
      for (int i = 0; i < n; i++) scanf("%s", a[i]);
      for (int i = 0; i < n; i++) {
         for (int j = 0; j < m; j++) {
            if ('@' == a[i][j]) xyFr.x = i, xyFr.y = j;
            if ('*' == a[i][j]) xyTo.x = i, xyTo.y = j;
         }
      }
      a[xyFr.x][xyFr.y] = a[xyTo.x][xyTo.y] = '.';
      DBG_PRINT("  >>>%d,%d  ", xyFr.x, xyFr.y);
      dump();
      bfs(xyFr.x, xyFr.y);
      printf("%d\n", ans[xyTo.x][xyTo.y] ? ans[xyTo.x][xyTo.y] : -1);
   }
}

int main() {
   work1();
   return 0;
}